/**********************************************************************************************************************
 * @file    nmea.h
 * @author  Queclink Jason.Huang
 * @date    2018-12-29
 * @brief   NMEA (National Marine Electronics Association) Protocol basic source.
 *
 * Copyright (C) 2018 Queclink Wireless Solutions (ShenZhen) Co., Ltd. All Rights Reserved.
 *
 * @attention
 *
 * @usage
 *
 *********************************************************************************************************************/


#ifndef __GNSS_NMEA_H
#define __GNSS_NMEA_H

/* includes ---------------------------------------------------------------------------------------------------------*/
#include <stdbool.h>
#include <gnss_public.h>

#ifdef __cplusplus
extern "C" {
#endif

/* nmea协议消息解析步骤 */
typedef enum{
	STAGE_HEAD,					/* 接收nmea消息起始位'$' */
	STAGE_DATA,					/* 接收nmea消息数据 */
	STAGE_BCC_H,				/* 校验位高字节 */
	STAGE_BCC_L,				/* 校验位低字节 */
	STAGE_TAIL_CR,				/* '\r' */
	STAGE_TAIL_LF				/* '\n' */
}nmea_parse_stage_t;

/* enable messages */
#define RMC_MASK  	0x01
#define GGA_MASK	0x02
#define GSA_MASK	0x04
#define GSV_MASK	0x08
#define TXT_MASK	0x10
/* disable messages */
#define VTG_MASK	0x01		/* disable */
#define GLL_MASK	0x02		/* disable */

/* name:	消息名
 * handler:	对应的解析函数
 */
typedef struct{
	const char * name;
	void (*handler)(int argc, char *argv[]);
}nmea_parse_handler_t;

/* 位置信息标准差, 单位m */
struct gnss_stderr {
    double  lat;        /* 纬度误差的标准差 */
    double  lng;        /* 经度误差的标准差 */
    double  alt;        /* 高度误差的标准差 */
};

typedef struct{
	unsigned char		previous_sec;		/* 上一次 */
	short 				previous_ms;
	nmea_parse_stage_t 	stage;				/* 接收步骤 */
	unsigned char 		buffer[256];		/* 接收到的nmea消息 */
    unsigned char 		recv_nmea_msg;		/* 接收消息掩码 */
	unsigned char		has_disable_msg;	/* 检查被禁止的信息输出 */
    unsigned char 		rmc_lost_cnt;		/* rmc消息缺失计数 */
	char* 				ptr_list[32];		/* nmea消息分割后得到的字符串地址列表 */
	unsigned short 		length;				/* 消息长度 */
	unsigned short		stream_valid_mask;
	unsigned int 		time_out;
	struct fix_info 	raw_info;			/* 当前gps的原始数据 */
    struct gnss_stderr  stderr_;             /* 位置信息标准差 */
}nmea_protocol_parse_t;


int nmea_protocol_parse(unsigned char *buf, int len, void *ext_hdr, int num);
nmea_protocol_parse_t* get_nmea_manage_context(void);
int nmea_string_split(unsigned char *str, const char * separator, char *list[], int list_len);
bool nmea_check_crc(const unsigned char *buf);

void nmea_gga_parse(int argc, char *argv[]);
void nmea_txt_parse(int argc, char *argv[]);
void nmea_gsa_parse(int argc, char *argv[]);
void nmea_gsv_parse(int argc, char *argv[]);
void nmea_rmc_parse(int argc, char *argv[]);
void nmea_gst_parse(int argc, char *argv[]);

void gnss_nmea_recv(char *nema_msg);

#ifdef __cplusplus
}
#endif

#endif /* __GNSS_NMEA_H */
